﻿// //  ********************************************************************************
// //  Copyright (C) 2016 Sebastian Kenter. All rights reserved.
// // 
// //  Name    : PhotonServerProject | PhotonServerFramework | ClientPeerRegistry.cs
// //  Created : 2016 - 03 - 21 13:12
// //  Modified: 2016 - 04 - 18 09:37
// //  ********************************************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using ExitGames.Logging;
using NHibernate;
using PhotonServerCommon.Entities.Domain;
using PhotonServerFramework.Implementation.Database;
using PhotonServerFramework.Interfaces.Client;

namespace PhotonServerFramework.Implementation.Client
{
    public class ClientPeerRegistry : IClientPeerRegistry
    {
        public ILogger Logger { get; }
        private readonly Dictionary<Guid, IClientPeer> _clientPeers = new Dictionary<Guid, IClientPeer>();

        public ClientPeerRegistry(ILogger logger)
        {
            Logger = logger;
        }

        public bool RegisterClientPeer(IClientPeer clientPeer)
        {
            if (_clientPeers.ContainsKey(clientPeer.ClientPeerId))
            {
                Logger.ErrorFormat("Cannot register the same client twice (Guid: {0})", clientPeer.ClientPeerId);
                return false;
            }

            _clientPeers.Add(clientPeer.ClientPeerId, clientPeer);

            return true;
        }

        public bool UnregisterClientPeer(Guid peerId)
        {
            if (!_clientPeers.ContainsKey(peerId))
            {
                Logger.ErrorFormat("Cannot unregister cause client not registered (Guid: {0})", peerId);
                return false;
            }

            _clientPeers.Remove(peerId);
            Logger.InfoFormat("Unregistered client peer with id = {0}", peerId);
            return true;
        }

        public IClientPeer GetClientPeerById(Guid peerId)
        {
            return _clientPeers.FirstOrDefault(c => c.Key == peerId).Value;
        }

        public Dictionary<Guid, IClientPeer> GetClientPeers()
        {
            return _clientPeers;
        }

        public void UnregisterClientPeers(Guid serverId)
        {
            IList<ClientPeerT> clients = null;

            using (ISession session = SessionManager.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    try
                    {
                        clients =
                            session.QueryOver<ClientPeerT>()
                                .Where(c => c.ConnectedServerId == serverId.ToString())
                                .List<ClientPeerT>();
                        transaction.Commit();
                    }
                    catch (Exception ex)
                    {
                        Logger.ErrorFormat("Operation failed with: {0}", ex.Message);
                        transaction.Rollback();
                    }
                }

                session.Close();
            }

            if (clients == null) return;

            foreach (ClientPeerT client in clients)
            {
                UnregisterClientPeer(Guid.Parse(client.PeerId));
                using (ISession session = SessionManager.OpenSession())
                {
                    using (ITransaction transaction = session.BeginTransaction())
                    {
                        try
                        {
                            session.Delete(client);
                            transaction.Commit();
                        }
                        catch (Exception ex)
                        {
                            Logger.ErrorFormat("Operation failed with: {0}", ex.Message);
                            transaction.Rollback();
                        }
                    }

                    session.Close();
                }
            }
        }
    }
}
